#pragma once

#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<cstdlib>
#include<unistd.h>
#include<iostream>
namespace Tserver
{
#define BACKLOG 5
  class TcpServer
  {
    typedef void(*handler_t)(int);
    private:
      int port; 
      int listen_sock;
    public:
      TcpServer(int _port):port(_port),listen_sock(-1)
      {}
      void Init()
      {
        listen_sock=socket(AF_INET,SOCK_STREAM,0);
        if(listen_sock<0)
        {
          std::cerr<<"socket error"<<std::endl;
          exit(2);
        }
        struct sockaddr_in ser;
        ser.sin_family=AF_INET;
        ser.sin_port=htons(port);
        ser.sin_addr.s_addr=INADDR_ANY;
        int e=bind(listen_sock,(struct sockaddr*)&ser,sizeof(ser));
        if(e<0)
        {
          std::cerr<<"bind error"<<std::endl;
          exit(3);
        }
        e=listen(listen_sock,BACKLOG);
        if(e<0)
        {
          std::cerr<<"listen error"<<std::endl;
          exit(4);
        }
    }
    void Loop(handler_t handler)
    {

      while(true)
      {
        int sock;
        struct sockaddr_in peer;
        socklen_t len=sizeof(peer);
        sock=accept(listen_sock,(struct sockaddr*)&peer,&len);
        if(sock<0)
        {
          std::cerr<<"accept error"<<std::endl;
        }
        //验证一下对端数据
        std::cout<<"debug sock "<<sock<<std::endl;

        uint16_t peer_port=ntohs(peer.sin_port);
        char * c=inet_ntoa(peer.sin_addr); 
        std::cout<<"port "<<peer_port<<std::endl;
        std::cout<<"ip "<<c<<std::endl;
        //链接成功，从客户端读数据
        
        //处理数据
        handler(sock);

        //处理完数据后，关闭文件描述符
        //close(sock);
      }
    }
    ~TcpServer()
    {
      close(listen_sock);
    }
  };
}
